package com.linkstec.mvel2;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
import org.mvel2.MVEL;
import org.mvel2.compiler.ExecutableAccessor;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.integration.impl.MapVariableResolverFactory;

/**
 * 
 * 20190329 liuyl
 */
public class Mvel2Tester {

	private static final Logger logger = LogManager.getLogger();
    public static void main(String[] args) {

        Person personInst = new Person();
        personInst.setName("Mr.Foo");

        // 判断相等
        Object objResult = MVEL.eval("name == 'Mr.Foo'", personInst);
        logger.info("++++++++++++++++++++++++++++++++++++++++++++++");
        logger.info("objResult=" + objResult);

        // 取值
        String strResult = (String) MVEL.eval("name", personInst);
        System.out.println("strResult=" + strResult);

        // 计算
        Map<String, Integer> vars = new HashMap<String, Integer>();
        vars.put("x", new Integer(5));
        vars.put("y", new Integer(10));

        // 第一种方式
        Integer intResult1 = (Integer) MVEL.eval("x + y", vars);
        System.out.println("x + y intResult=" + intResult1);
        Integer intResult2 = (Integer) MVEL.eval("x - y", vars);
        System.out.println("x - y intResult=" + intResult2);
        Integer intResult3 = (Integer) MVEL.eval("x * y", vars);
        System.out.println("x * y intResult=" + intResult3);
        Double intResult4 = (Double) MVEL.eval("x / y", vars);
        System.out.println("x / y intResult=" + intResult4);
        // 第二种方式
        ExecutableAccessor compiled = (ExecutableAccessor) MVEL.compileExpression("x * y");
        intResult1 = (Integer) MVEL.executeExpression(compiled, vars);
        System.out.println("x * y intResult=" + intResult1);
        logger.info("++++++++++++++++++++++++++++++++++++++++++++++");

    }

    /**
     * 基本解析表达式
     */
    @Test
    public void test1(){
        String expression ="foobar > 99";
        Map<String, Object> vars = new HashMap<String, Object>();
        vars.put("foobar",new Integer(100));
        // We know this expressionshould return a boolean.
//        Boolean result = (Boolean) MVEL.eval(expression, vars);
        Boolean result = MVEL.evalToBoolean(expression, vars);
        if (result.booleanValue()) {
            System.out.println("Itworks!");
        }
    }

    /**
     * 变量判空
     */
    @Test
    public void test2(){
        String expression = "a == empty && b == empty";

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("a", "");
        paramMap.put("b", null);
        Object object = MVEL.eval(expression, paramMap);
        System.out.println(object); // true
    }
    /**
     * 
     */
    @Test
    public void test3(){
        HashMap<Object, Object> srcMap = new HashMap<>();
        srcMap.put("name","zs");
        srcMap.put("age",10);
        srcMap.put("sex","女");
//字段映射关系
        HashMap<String, String> mapping = new HashMap<>();
        mapping.put("name","name");
        mapping.put("age","age");
//这里先把当前年份写死为2019
        mapping.put("birthYear","2019-age");
//目标对象
        HashMap<Object, Object> targetMap = new HashMap<>();
//k为目标表字段，v为转换规则
        mapping.forEach((k,v)->{
            Object reValue = MVEL.eval(v,srcMap);
            System.out.println(v+":"+reValue);
            targetMap.put(k,reValue);
        });
        System.out.println("源对象"+srcMap); //源对象{sex=女, name=zs, age=10}
        System.out.println("目标对象"+targetMap); //目标对象{birthYear=2009, name=zs, age=10}
    }

    /**
     * 获取对象属性
     */
    @Test
    public void test4(){
    	Person person = new Person();
    	person.setName("1234");
        String expression = "person.Name = '123'";
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("person",person);
        Object object = MVEL.eval(expression, paramMap);
        System.out.println(object); // true
    }

    /**
     * null 和nil 都表示空
     */
    @Test
    public void test5(){
        String expression = "a == null && b == nil";
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("a", null);
        paramMap.put("b", null);
        Object object = MVEL.eval(expression, paramMap);
        System.out.println(object); // true
    }

    /**
     * 两种解析表达式方式
     */
    @Test
    public void test6(){
    	Person foo = new Person();
        foo.setName("test");
        Map<String, Object> context = new HashMap<String, Object>();
        String expression = "foo.Name == 'test'";
        VariableResolverFactory functionFactory = new MapVariableResolverFactory(context);
        context.put("foo",foo);
        Boolean result = (Boolean) MVEL.eval(expression,functionFactory);
        System.out.println(result);

        Serializable compileExpression = MVEL.compileExpression(expression);
        result = (Boolean) MVEL.executeExpression(compileExpression, context, functionFactory);
        System.out.print(result);
    }

    /**
     *基本表达式计算,map工厂
     */
    @Test
    public void test7(){
        String exp = "a + b > c";
        Map<String, Object> varsMap = new HashMap<String, Object>();
        varsMap.put("a", 1); varsMap.put("b", 2);varsMap.put("c", 2);
        VariableResolverFactory factory = new MapVariableResolverFactory(varsMap);
        Object eval = MVEL.eval(exp, factory);
        System.out.println(eval);
    }


}